import javalang

# Java 代码示例
java_code = """
package com.pingpongx.business.payout.api.service;

import com.pingpongx.business.common.dto.OrderDTO;
import com.pingpongx.business.payout.api.dto.request.FileOrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.MassOrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.OrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.TripartiteOrderPayRequest;
import com.pingpongx.business.payout.api.dto.request.emailPay.MassEmailOrderPayRequest;
import com.pingpongx.business.payout.api.dto.response.EmailPay.FileEmailPayResponse;
import com.pingpongx.business.payout.api.dto.response.FileOrderPayResponse;
import com.pingpongx.business.payout.api.dto.response.MassOrderPayResponse;
import com.pingpongx.business.payout.api.dto.response.tripartite.TripartiteOrderPayResponse;

/**
 * PayoutService
 */
public interface PayoutService {

    String version = "1.0";

    /**
     * 单笔下单场景(全业务)
     * /api/front/payout/createTransferScaOrder
     * @param request
     * @return
     */
    OrderDTO createOrder(OrderPayRequest request);
    OrderDTO createVatOrder(OrderPayRequest request);
    OrderDTO createWithdrawOrder(OrderPayRequest request);
    OrderDTO createSupplierOrder(OrderPayRequest request);
    OrderDTO createExchangeOrder(OrderPayRequest request);

    /**
     * 创建需要安全验证【短信验证】的订单(全业务)
     * @param request
     * @return
     */
    OrderDTO createScaOrder(OrderPayRequest request);
    OrderDTO createSupplierScaOrder(OrderPayRequest request);
    OrderDTO createWithdrawScaOrder(OrderPayRequest request);
    OrderDTO createVatScaOrder(OrderPayRequest request);

    /**
     * 接入三方授权创建出金单
     * @param request
     * @return
     */
    TripartiteOrderPayResponse createThirdPartOrder(TripartiteOrderPayRequest request);


    /**
     * 创建邮件方式订单
     * @param request
     * @return
     */
    OrderDTO createEmailPayOrder(OrderPayRequest request);

    /**
     * 创建能者供应商订单
     */
    OrderDTO createCapSupplierOrder(OrderPayRequest request);

    /**
     * 创建能者转账订单
     */
    OrderDTO createCapTransferOrder(OrderPayRequest request);


    /**
     * 检查订单金额是否受限
     */
    boolean checkOrderAmountLimit(OrderPayRequest request);

    /**
     * 创建requestPay订单
     * @param request
     * @return
     */
    OrderDTO createRequestPayOrder(OrderPayRequest request);

    /**
     * 文件形式批量操作订单
     * @param request
     * @return
     */
    FileOrderPayResponse createFileOrder(FileOrderPayRequest request);

    /**
     * 批量付款Group模式
     * @param request
     * @return
     */
    MassOrderPayResponse createMassOrder(MassOrderPayRequest request);

    /**
     * 批量EmailPay模式
     * @param request 请求数据
     * @return
     */
    FileEmailPayResponse createEmailFileOrder(MassEmailOrderPayRequest request);

    /**
     * 冻结订单(收银台模式下单分两步。1.预下单(createOrder创建订单)，2.冻结订单)
     * @param clientId
     * @param orderId
     * @return
     */
    OrderDTO frozenOrder(String clientId,String orderId);

    /**
     * 主动取消订单
     */
    void cancelOrder(String clientId, String orderId);

    /**
     * 订单过期
     * @param clientId
     * @param orderId
     */
    void expiredOrder(String clientId, String orderId);

    /**
     * 订单能否取消
     */
    boolean orderCanCancel(String clientId, String orderId);

    /**
     * 更换订单BA(boss需求)(clientId,orderId,bizId)
     * @param orderDTO
     */
    void changeOrderBA(OrderDTO orderDTO);

    void declineOnlineOrders(String clientId);

    /**
     * 待激活订单激活（目前只有us区）
     * @param clientId
     */
    void activeOrders(String clientId);

    /**
     * 更新用户订单中用户level信息 （目前只有us区）
     * @param clientId
     */
    @Deprecated
    void updateOrdersUserLevelByKycPass(String clientId);

    /**
     * 更新订单第三方失败原因
     * @param clientId
     * @param orderId
     * @param failReason
     */
    void updateOrderTripartiteFailReason(String clientId, String orderId, String failReason);
}

"""


class JavaAnalyzer:
    def __init__(self, filepath, source_code):
        self.filepath = filepath
        self.source_code = source_code
        self.source_lines = source_code.split("\n")
        self.nodes = []
        self.package_name = ""
        self.imports = []
        self.inheritance_info = []
        # 构建位置索引以便快速查找节点位置
        self.node_positions = {}

    def _extract_code_block(self, start_line, end_line):
        """提取指定行范围的代码"""
        if start_line <= 0 or start_line > len(self.source_lines):
            return ""

        start_idx = start_line - 1
        end_idx = min(end_line, len(self.source_lines))

        return "\n".join(self.source_lines[start_idx:end_idx])

    def _get_position_info(self, node):
        """获取节点的完整位置信息"""
        if hasattr(node, 'position') and node.position:
            return {
                'line': node.position.line,
                'column': node.position.column
            }
        return None

    def _find_method_end_line(self, start_line, method_name):
        """通过代码结构查找方法的实际结束行"""
        if start_line <= 0 or start_line > len(self.source_lines):
            return start_line

        # 查找方法签名所在行
        signature_line = start_line - 1

        # 对于接口方法（没有方法体），通常以分号结束
        for i in range(signature_line, len(self.source_lines)):
            line = self.source_lines[i].strip()
            if ';' in line:
                # 找到分号，这是接口方法的结束
                return i + 1
            if '{' in line:
                # 如果找到了开括号，说明有方法体
                break

        # 如果有方法体，需要匹配括号
        brace_count = 0
        found_first_brace = False

        for i in range(signature_line, len(self.source_lines)):
            line = self.source_lines[i]
            for char in line:
                if char == '{':
                    brace_count += 1
                    found_first_brace = True
                elif char == '}':
                    brace_count -= 1
                    if found_first_brace and brace_count == 0:
                        return i + 1

        # 如果没找到结束，返回估算值
        return min(start_line + 5, len(self.source_lines))

    def _find_class_or_interface_end_line(self, start_line, node):
        """查找类或接口的结束行"""
        if start_line <= 0 or start_line > len(self.source_lines):
            return start_line

        # 收集所有成员的结束位置
        member_end_lines = []

        if hasattr(node, 'body') and node.body:
            for member in node.body:
                member_start = self._get_line_number(member)
                if member_start > 0:
                    if isinstance(member, javalang.tree.MethodDeclaration):
                        member_end = self._find_method_end_line(member_start, member.name)
                    elif isinstance(member, javalang.tree.FieldDeclaration):
                        # 字段声明通常在一行，但可能有多行注释
                        member_end = self._find_field_end_line(member_start)
                    else:
                        # 其他成员类型的估算
                        member_end = member_start + 1
                    member_end_lines.append(member_end)

        if member_end_lines:
            # 找到最后一个成员的结束位置
            last_member_end = max(member_end_lines)

            # 查找类/接口的结束括号
            for i in range(last_member_end - 1, len(self.source_lines)):
                line = self.source_lines[i].strip()
                if '}' in line:
                    return i + 1

            return min(last_member_end + 2, len(self.source_lines))

        # 如果没有成员，通过括号匹配查找
        brace_count = 0
        found_first_brace = False

        for i in range(start_line - 1, len(self.source_lines)):
            line = self.source_lines[i]
            for char in line:
                if char == '{':
                    brace_count += 1
                    found_first_brace = True
                elif char == '}':
                    brace_count -= 1
                    if found_first_brace and brace_count == 0:
                        return i + 1

        return min(start_line + 10, len(self.source_lines))

    def _find_field_end_line(self, start_line):
        """查找字段声明的结束行"""
        if start_line <= 0 or start_line > len(self.source_lines):
            return start_line

        # 字段通常以分号结束
        for i in range(start_line - 1, min(start_line + 5, len(self.source_lines))):
            line = self.source_lines[i].strip()
            if ';' in line:
                return i + 1

        return start_line

    def _get_end_line_number(self, node, start_line):
        """获取节点的准确结束行号"""
        try:
            # 根据节点类型使用不同的策略
            if isinstance(node, javalang.tree.MethodDeclaration):
                return self._find_method_end_line(start_line, node.name)
            elif isinstance(node, (javalang.tree.ClassDeclaration, javalang.tree.InterfaceDeclaration)):
                return self._find_class_or_interface_end_line(start_line, node)
            elif isinstance(node, javalang.tree.FieldDeclaration):
                return self._find_field_end_line(start_line)
            else:
                # 对于其他类型，使用通用方法
                if hasattr(node, 'body') and node.body:
                    max_child_line = start_line
                    for child in node.body:
                        child_line = self._get_line_number(child)
                        if child_line > max_child_line:
                            # 递归获取子节点的结束行
                            child_end = self._get_end_line_number(child, child_line)
                            if child_end > max_child_line:
                                max_child_line = child_end
                    return max_child_line + 1
                return start_line + 1
        except Exception as e:
            print(f"Error getting end line for node: {e}")
            return min(start_line + 5, len(self.source_lines))

    def _get_line_number(self, node):
        """获取节点的行号"""
        try:
            if hasattr(node, "position") and node.position:
                return node.position.line
        except:
            pass
        return 1

    def _extract_method_calls_from_node(self, node):
        """从节点中提取方法调用"""
        calls = []

        def collect_calls(n):
            if isinstance(n, javalang.tree.MethodInvocation):
                calls.append(n.member)
            elif isinstance(n, javalang.tree.ClassCreator):
                # 构造函数调用
                if hasattr(n, "type") and hasattr(n.type, "name"):
                    calls.append(n.type.name)

            # 递归遍历子节点
            if hasattr(n, "children"):
                for child in n.children:
                    if child:
                        if isinstance(child, list):
                            for item in child:
                                if item:
                                    collect_calls(item)
                        else:
                            collect_calls(child)

        try:
            collect_calls(node)
        except Exception as e:
            print(f"Error extracting method calls: {e}")

        return calls

    def _visit_method(self, node, parent_class):
        """访问方法声明"""
        method_name = node.name
        full_method_name = f"{parent_class}.{method_name}"

        start_line = self._get_line_number(node)
        end_line = self._get_end_line_number(node, start_line)
        code_block = self._extract_code_block(start_line, end_line)

        # 获取参数信息
        parameters = []
        if hasattr(node, "parameters") and node.parameters:
            for param in node.parameters:
                parameters.append(
                    {
                        "name": param.name,
                        "type": str(param.type) if param.type else "unknown",
                    }
                )

        # 提取方法调用
        method_calls = self._extract_method_calls_from_node(node)

        method_node = {
            "name": full_method_name,
            "type": "method",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
            "parameters": parameters,
            "return_type": str(node.return_type) if node.return_type else "void",
            "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
            "method_calls": method_calls,
        }
        self.nodes.append(method_node)

    def _visit_interface(self, node):
        """访问接口声明"""
        interface_name = node.name

        start_line = self._get_line_number(node)
        end_line = self._get_end_line_number(node, start_line)
        code_block = self._extract_code_block(start_line, end_line)

        # 接口可以extends其他接口
        extends_interfaces = []
        if hasattr(node, "extends") and node.extends:
            extends_interfaces = [ext.name for ext in node.extends]

        interface_node = {
            "name": interface_name,
            "type": "interface",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
            "extends": extends_interfaces,
            "is_interface": True,
            "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
        }
        self.nodes.append(interface_node)

        # 记录继承信息
        for parent_interface in extends_interfaces:
            self.inheritance_info.append((interface_name, parent_interface, "extends"))

        # 处理接口方法
        if hasattr(node, "body"):
            for member in node.body:
                if isinstance(member, javalang.tree.MethodDeclaration):
                    self._visit_method(member, interface_name)
                elif isinstance(member, javalang.tree.FieldDeclaration):
                    self._visit_field(member, interface_name)

    def _visit_field(self, node, parent_class):
        """访问字段声明"""
        for declarator in node.declarators:
            field_name = declarator.name
            full_field_name = f"{parent_class}.{field_name}"

            start_line = self._get_line_number(node)
            end_line = self._find_field_end_line(start_line)
            code_block = self._extract_code_block(start_line, end_line)

            field_node = {
                "name": full_field_name,
                "type": "field",
                "code": code_block,
                "start_line": start_line,
                "end_line": end_line,
                "field_type": str(node.type) if node.type else "unknown",
                "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
                "initializer": str(declarator.initializer) if declarator.initializer else None
            }
            self.nodes.append(field_node)

    def _visit_class(self, node):
        """访问类声明"""
        class_name = node.name

        start_line = self._get_line_number(node)
        end_line = self._get_end_line_number(node, start_line)
        code_block = self._extract_code_block(start_line, end_line)

        # 获取继承信息
        extends_class = None
        if hasattr(node, "extends") and node.extends:
            extends_class = node.extends.name

        implements_interfaces = []
        if hasattr(node, "implements") and node.implements:
            implements_interfaces = [impl.name for impl in node.implements]

        class_node = {
            "name": class_name,
            "type": "class",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
            "extends": extends_class,
            "implements": implements_interfaces,
            "is_interface": False,
            "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
        }
        self.nodes.append(class_node)

        # 记录继承信息
        if extends_class:
            self.inheritance_info.append((class_name, extends_class, "extends"))
        for impl_interface in implements_interfaces:
            self.inheritance_info.append((class_name, impl_interface, "implements"))

        # 处理类成员
        if hasattr(node, "body"):
            for member in node.body:
                if isinstance(member, javalang.tree.MethodDeclaration):
                    self._visit_method(member, class_name)
                elif isinstance(member, javalang.tree.FieldDeclaration):
                    self._visit_field(member, class_name)
                elif isinstance(member, javalang.tree.ConstructorDeclaration):
                    self._visit_constructor(member, class_name)

    def _visit_constructor(self, node, parent_class):
        """访问构造函数"""
        constructor_name = node.name
        full_name = f"{parent_class}.{constructor_name}"

        start_line = self._get_line_number(node)
        end_line = self._get_end_line_number(node, start_line)
        code_block = self._extract_code_block(start_line, end_line)

        # 获取参数信息
        parameters = []
        if hasattr(node, "parameters") and node.parameters:
            for param in node.parameters:
                parameters.append(
                    {
                        "name": param.name,
                        "type": str(param.type) if param.type else "unknown",
                    }
                )

        # 提取方法调用
        method_calls = self._extract_method_calls_from_node(node)

        constructor_node = {
            "name": full_name,
            "type": "constructor",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
            "parameters": parameters,
            "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
            "method_calls": method_calls,
        }
        self.nodes.append(constructor_node)

    def _visit_enum(self, node):
        """访问枚举声明"""
        enum_name = node.name

        start_line = self._get_line_number(node)
        end_line = self._get_end_line_number(node, start_line)
        code_block = self._extract_code_block(start_line, end_line)

        enum_node = {
            "name": enum_name,
            "type": "enum",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
            "modifiers": [str(mod) for mod in node.modifiers] if node.modifiers else [],
        }
        self.nodes.append(enum_node)

        # 处理枚举成员
        if hasattr(node, "body"):
            if hasattr(node.body, "constants"):
                for constant in node.body.constants:
                    self._visit_enum_constant(constant, enum_name)

            # 枚举也可以有方法和字段
            if hasattr(node.body, "declarations"):
                for member in node.body.declarations:
                    if isinstance(member, javalang.tree.MethodDeclaration):
                        self._visit_method(member, enum_name)
                    elif isinstance(member, javalang.tree.FieldDeclaration):
                        self._visit_field(member, enum_name)

    def _visit_enum_constant(self, node, parent_enum):
        """访问枚举常量"""
        constant_name = node.name
        full_name = f"{parent_enum}.{constant_name}"

        # 枚举常量通常在一行
        start_line = self._get_line_number(node)
        end_line = start_line
        code_block = self._extract_code_block(start_line, end_line)

        enum_constant_node = {
            "name": full_name,
            "type": "enum_constant",
            "code": code_block,
            "start_line": start_line,
            "end_line": end_line,
        }
        self.nodes.append(enum_constant_node)

    def _visit_type(self, node):
        """访问类型声明节点"""
        if isinstance(node, javalang.tree.ClassDeclaration):
            self._visit_class(node)
        elif isinstance(node, javalang.tree.InterfaceDeclaration):
            self._visit_interface(node)
        elif isinstance(node, javalang.tree.EnumDeclaration):
            self._visit_enum(node)

    def analyze(self, tree):
        """分析Java语法树并提取节点"""
        if hasattr(tree, "package") and tree.package:
            self.package_name = tree.package.name

        # 提取import信息
        if hasattr(tree, "imports"):
            for import_decl in tree.imports:
                import_info = {
                    "path": import_decl.path,
                    "static": getattr(import_decl, "static", False),
                    "wildcard": getattr(import_decl, "wildcard", False),
                }
                self.imports.append(import_info)

        # 分析类型声明
        if hasattr(tree, "types"):
            for type_decl in tree.types:
                self._visit_type(type_decl)

        return self.nodes


# 测试改进后的分析器
print("=" * 80)
print("测试改进后的Java代码分析器")
print("=" * 80)

tree = javalang.parse.parse(java_code)
analyzer = JavaAnalyzer("PayoutService.java", java_code)
nodes = analyzer.analyze(tree)

# 打印结果，重点关注行号信息
print(f"\n包名: {analyzer.package_name}")
print(f"\n导入语句数量: {len(analyzer.imports)}")
print(f"\n找到的节点数量: {len(nodes)}")

print("\n" + "=" * 80)
print("节点详情（重点查看行号）:")
print("=" * 80)

for node in nodes:
    print(f"\n节点名称: {node['name']}")
    print(f"类型: {node['type']}")
    print(f"起始行: {node['start_line']}")
    print(f"结束行: {node['end_line']}")
    print(f"代码行数: {node['end_line'] - node['start_line'] + 1}")

    # 显示代码片段的前后几行
    if node['code']:
        code_lines = node['code'].split('\n')
        if len(code_lines) > 0:
            print(f"代码首行: {code_lines[0][:80]}...")
            if len(code_lines) > 1:
                print(f"代码末行: {code_lines[-1][:80]}...")
    print("-" * 40)

print("\n" + "=" * 80)
print("继承关系:")
print("=" * 80)
for child, parent, relation in analyzer.inheritance_info:
    print(f"{child} {relation} {parent}")